import asyncio
import logging
import os
import queue
import random
import re
import threading

import cv2
from PIL import Image, ImageDraw, ImageFilter, ImageFont
from aiogram import types
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters import Text
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.types import ParseMode

import client
import client_kb
import sqlite_db
from common_utils import compare_date, paste_watermark
from create_bot import dp
from .utils import de_transliterate, is_deutsch

logger = logging.getLogger(__name__)


def process_generate_signature(user_id, data):
    text = data.capitalize()
    if is_deutsch(text):
        text = de_transliterate(text)
    txt = Image.new("RGBA", (1900, 600), (255, 255, 255, 0))
    go_txt = ImageDraw.Draw(txt)
    fnt1 = ImageFont.truetype(f"./fonts/1.ttf", size=270)
    go_txt.text(xy=(200, 50), text=f"{text}", font=fnt1, fill="#000000")
    fnt2 = ImageFont.truetype(f"./fonts/2.ttf", size=190)
    go_txt.text(xy=(800, 50), text=f"{text}", font=fnt2, fill="#000000", stroke_width=1)
    fnt3 = ImageFont.truetype(f"./fonts/3.ttf", size=200)
    go_txt.text(
        xy=(1400, 50), text=f"{text}", font=fnt3, fill="#000000", stroke_width=1
    )
    fnt4 = ImageFont.truetype(f"./fonts/4.ttf", size=100)
    go_txt.text(
        xy=(200, 400), text=f"{text}", font=fnt4, fill="#000000", stroke_width=1
    )
    fnt5 = ImageFont.truetype(f"./fonts/5.ttf", size=150)
    go_txt.text(
        xy=(800, 400), text=f"{text}", font=fnt5, fill="#000000", stroke_width=1
    )
    fnt6 = ImageFont.truetype(f"./fonts/6.ttf", size=80)
    go_txt.text(xy=(1400, 400), text=f"{text}", font=fnt6, fill="#000000")
    fnt66 = ImageFont.truetype(f"./fonts/66.ttf", size=80)
    go_txt.text(xy=(1430, 440), text=f"k", font=fnt66, fill="#000000")
    txt_blur = txt.filter(ImageFilter.GaussianBlur(radius=1))
    holst = Image.new("RGBA", (1900, 600), (255, 255, 255, 255))
    choose_signature = Image.alpha_composite(holst, txt_blur)
    choose_signature.save(f"./files/de_id/photo_usr/{user_id}_choose_signature.png")


def process_passport_photo(user_id):
    try:
        # Load the image and face detection classifier
        img = cv2.imread(f"./files/de_id/photo_usr/{user_id}.png", cv2.IMREAD_UNCHANGED)
        face_cascade = cv2.CascadeClassifier(
            f"./data/haarcascade_frontalface_default.xml"
        )

        # Detect faces in the image
        faces = face_cascade.detectMultiScale(img, 1.2, 5)

        # If faces are detected, crop and resize the image
        if len(faces) != 0:
            (x, y, w, h) = faces[0]
            h_top = int(h * 0.4)
            h_bottom = int(h * 0.3)
            w_left = int(w * 0.2)
            w_right = int(w * 0.2)
            x_left = max(0, x - w_left)
            x_right = min(img.shape[1], x + w + w_right)
            w_new = x_right - x_left
            y_top = max(0, y - h_top)
            y_bottom = min(img.shape[0], y + h + h_bottom)
            h_new = y_bottom - y_top

            cropped_img = img[y_top : y_top + h_new, x_left : x_left + w_new]
            cropped_img_pil = Image.fromarray(
                cv2.cvtColor(cropped_img, cv2.COLOR_BGRA2RGBA)
            )

            # Resize the image proportionally to the width of 264px
            target_width = 367
            width_ratio = target_width / cropped_img_pil.width
            new_width = target_width
            new_height = int(cropped_img_pil.height * width_ratio)
            resized_width = cropped_img_pil.resize(
                (new_width, new_height), Image.ANTIALIAS
            )

            # Resize the image proportionally to the height of 345px
            target_height = 484
            height_ratio = target_height / resized_width.height
            new_height = target_height
            new_width = int(resized_width.width * height_ratio)
            resized_height = resized_width.resize(
                (new_width, new_height), Image.ANTIALIAS
            )

            # Center crop the image to get the width of 264px
            left = (resized_height.width - target_width) / 2
            top = 0
            right = (resized_height.width + target_width) / 2
            bottom = new_height
            cropped_resized = resized_height.crop((left, top, right, bottom))

            # Convert the image to grayscale and keep the alpha channel
            grayscale_img = cropped_resized.convert("RGBA")
            grayscale_img.putalpha(cropped_resized.getchannel("A"))

            # Save the processed image with the alpha channel
            grayscale_img.save(f"./files/de_id/photo_usr/{user_id}_w.png")
            os.remove(f"./files/de_id/photo_usr/{user_id}.png")
        else:
            print(f"No faces found in image for user_id {user_id}")
    except Exception as e:
        print(f"Error processing passport photo for user_id {user_id}: {str(e)}")


class FSM_DE_ID(StatesGroup):
    de_client_id = State()
    de_first_name = State()
    de_last_name = State()
    de_maiden_name = State()
    de_birth_date = State()
    de_nationality = State()
    de_birth_place = State()
    de_sex = State()
    de_client_signature_id = State()
    de_client_rfid = State()
    de_color_of_eyes = State()
    de_height = State()
    de_emission_date = State()
    de_authority = State()
    de_client_idex = State()
    de_client_city = State()
    de_client_street = State()
    de_client_house = State()
    de_client_photo = State()
    de_client_holo_id = State()
    de_size = State()
    de_edit_data = State()


data_fields = [
    {"title": "Имя", "key": "client_first_name"},
    {"title": "Фамилия", "key": "client_last_name"},
    {"title": "Девичья фамилия", "key": "client_maiden_name"},
    {"title": "Номер ID", "key": "client_id"},
    {"title": "Дата рождения", "key": "client_birth_date"},
    {"title": "Пол", "key": "client_sex"},
    {"title": "Национальность", "key": "client_nationality"},
    {"title": "Место рождения", "key": "client_birth_place"},
    {"title": "Номер карты", "key": "client_rfid"},
    {"title": "Цвет глаз", "key": "client_color_of_eyes"},
    {"title": "Дата выдачи", "key": "client_emission_date"},
    {"title": "Место выдачи", "key": "client_emission_city"},
    {"title": "Индекс", "key": "client_index"},
    {"title": "Город", "key": "client_city"},
    {"title": "Улица", "key": "client_street"},
    {"title": "Номер дома", "key": "client_house"},
    {"title": "Рост", "key": "client_height"},
    {"title": "Голограмма", "key": "client_holo_id"},
    {"title": "Подпись", "key": "client_signature_id"},
    {"title": "Фотография", "key": "client_photo"},
    {"title": "Размер", "key": "size"},
    # {"title": "Магнитная полоса", "key": "client_magnit"},
    # {"title": "MP3", "key": "client_MP3"},
]


def upper_case(message):
    message_upper = message.replace("ß", "ẞ").upper()
    return message_upper


back_kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
back_button = types.KeyboardButton(text="️Назад ◀️")
back_button_inline = types.InlineKeyboardButton(
    text="️Назад ◀️", callback_data="️Назад ◀️"
)
back_kb.add(back_button)


async def data_checkup(user_id: int, state: FSMContext):
    try:
        data = await state.get_data()
        checkup_text = "Данные клиента:\n"
        for field in data_fields:
            if field["key"] in data:
                checkup_text += f"✅{field['title']}: {data[field['key']]}\n"
            else:
                checkup_text += f"{field['title']}:\n"
        if "message_to_edit_id" in data:
            await dp.bot.delete_message(
                chat_id=user_id, message_id=data["message_to_edit_id"]
            )
        return (await dp.bot.send_message(chat_id=user_id, text=checkup_text))[
            "message_id"
        ]
    except:
        pass


async def delete_user_reply(user_id: int, message_id: int):
    try:
        await dp.bot.delete_message(chat_id=user_id, message_id=message_id)
    except Exception as e:
        logger.warning(f"Unable to delete user message: {e}")


@dp.message_handler(Text(equals="ID 🇩🇪"), state="*")
async def id_client_first_name_input(message: types.Message, state: FSMContext):
    await sqlite_db.sql_add_country_user(message.from_user.id, "de_id")
    await state.update_data(type="id")
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите имя✏️\n",
            parse_mode=ParseMode.HTML,
            reply_markup=back_kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_first_name.set()


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM_DE_ID.de_first_name
)
async def id_first_name_validate(message: types.Message, state: FSMContext):
    client_first_name = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^[A-Za-z `]+$", message.text) is not None or is_deutsch(message.text):
        client_first_name = message.text
    if client_first_name is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите имя в правильном формате.\n"
                "<i>Формат ввода: только латинские и немецкие буквы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл имя")
        await state.update_data(client_first_name=upper_case(client_first_name))
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_last_name_input(message, state)


async def id_client_last_name_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите фамилию✏️\n", parse_mode=ParseMode.HTML, reply_markup=back_kb
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_last_name.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_last_name
)
async def id_client_last_name_validate(message: types.Message, state: FSMContext):
    client_last_name = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^[A-Za-z `]+$", message.text) is not None or is_deutsch(message.text):
        client_last_name = message.text
    if client_last_name is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите фамилию в правильном формате.\n"
                "<i>Формат ввода: только латинские и немецкие буквы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл фамилию")
        await state.update_data(client_last_name=upper_case(client_last_name))
        data["sign"] = client_last_name.capitalize()
        if is_deutsch(data["sign"]):
            data["sign"] = de_transliterate(data["sign"])
        if len(data["sign"]) > 5:
            data["sign"] = data["sign"][: random.randint(3, 5)]
        await state.update_data(sign=data["sign"])
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_maiden_name_input(message, state)


async def id_client_maiden_name_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(types.KeyboardButton("Пропустить"), back_button)
    question_message_id = (
        await message.answer(
            "Введите девичью фамилию, в случае её наличия✏️\n",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_maiden_name.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_maiden_name
)
async def id_client_maiden_name_validate(message: types.Message, state: FSMContext):
    client_maiden_name = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(types.KeyboardButton("Пропустить"), back_button)
    if message.text is not None:
        client_maiden_name = message.text
    if client_maiden_name is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите девичью фамилию в правильном формате.\n"
                "<i>Формат ввода: только латинские и немецкие буквы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл фамилию")
        await state.update_data(client_maiden_name=upper_case(client_maiden_name))
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_id_input(message, state)


async def id_client_id_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(types.KeyboardButton(text="Сгенерировать"))
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите номер ID (8 цифр и букв)✏️\n",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_client_id.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_client_id
)
async def id_client_id_validate(message: types.Message, state: FSMContext):
    client_id = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    import string

    if message.text == "Сгенерировать":
        client_id = f"L{random.randrange(1,9)}{random.choice(string.ascii_letters)}{random.choice(string.ascii_letters)}{random.choice(string.ascii_letters)}{random.choice(string.ascii_letters)}{random.randrange(1,9)}{random.randrange(1,9)}{random.choice(string.ascii_letters)}".upper()
    elif message.text is not None:
        client_id = message.text

    if client_id is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(types.KeyboardButton(text="Сгенерировать"), back_button)
        question_message_id = (
            await message.answer(
                text="❌Введите номер ID в правильном формате.\n"
                "<i>Формат ввода: 8 цифр</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл ID")
        await state.update_data(client_id=client_id)
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_birth_date_input(message, state)


async def id_client_birth_date_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите дату рождения✏️\n" "<i>Формат ввода: дд.мм.гггг</i>",
            parse_mode=ParseMode.HTML,
            reply_markup=back_kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_birth_date.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_birth_date
)
async def id_client_birth_date_validate(message: types.Message, state: FSMContext):
    client_birth_date = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match(r"^\d{2}\.\d{2}\.\d{4}$", message.text) is not None:
        client_birth_date = message.text
    if client_birth_date is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите дату рождения в правильном формате.\n"
                "<i>Формат ввода: дд.мм.гггг</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл дату рождения")
        await state.update_data(client_birth_date=client_birth_date)
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_sex_input(message, state)


async def id_client_sex_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(types.KeyboardButton(text="Мужской 🙎🏻‍♂️"))
    kb.add(types.KeyboardButton(text="Женский 🙍🏻‍♀️"))
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Выберите пол\n", parse_mode=ParseMode.HTML, reply_markup=kb
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_sex.set()


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM_DE_ID.de_sex
)
async def id_client_sex_validate(message: types.Message, state: FSMContext):
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if message.text == "Мужской 🙎🏻‍♂️":
        sex = "M"
    elif message.text == "Женский 🙍🏻‍♀️":
        sex = "F"
    else:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(types.KeyboardButton(text="Мужской 🙎🏻‍♂️"))
        kb.add(types.KeyboardButton(text="Женский 🙍🏻‍♀️"), back_kb)
        question_message_id = (
            await message.answer(
                text="❌Выберите пол через клавиатуру.\n",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        return await state.update_data(question_message_id=question_message_id)
    logger.info(f"Пользователь {message.from_user.id} ввёл пол")
    await state.update_data(client_sex=sex)
    if "edit_mode" in data:
        return await start_generate_edit(message.from_user.id, state)
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    await id_client_nationality_input(message, state)


async def id_client_nationality_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(types.KeyboardButton("Deutsch"), back_button)
    question_message_id = (
        await message.answer(
            "Введите национальность✏️\n", parse_mode=ParseMode.HTML, reply_markup=kb
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_nationality.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_nationality
)
async def id_client_nationality_validate(message: types.Message, state: FSMContext):
    client_nationality = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^[A-Za-z `]+$", message.text) is not None or is_deutsch(message.text):
        client_nationality = message.text
    if client_nationality is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(types.KeyboardButton("Deutsch"), back_button)
        question_message_id = (
            await message.answer(
                text="❌Введите национальность в правильном формате.\n"
                "<i>Формат ввода: только латинские буквы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл фамилию")
        await state.update_data(client_nationality=upper_case(client_nationality))
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_birth_place_input(message, state)


async def id_client_birth_place_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите город рождения ✏️\n" "<i>Пример: HEINSBERG </i>\n",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_birth_place.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_birth_place
)
async def id_client_birth_place_validate(message: types.Message, state: FSMContext):
    client_birth_place = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    # if message.text == "Сгенерировать":
    #     cities_array = [
    #         "TORINO (TO)",
    #         "VERCELLI (VC)",
    #         "NOVARA (NV)",
    #         "CUNEO (CN)",
    #         "ASTI (AT)",
    #         "ALESSANDRIA (AL)",
    #         "BIELLA (BI)",
    #         "VARESE (VA)",
    #         "COMO (CO)",
    #         "SONDRIO (SO)",
    #         "MILANO (MI)",
    #         "BERGAMO (BG)",
    #         "BRESCIA (BS)",
    #         "PAVIA (PV)",
    #         "CREMONA (CR)",
    #         "MANTOVA (MN)",
    #         "LECCO (LC)",
    #         "LODI (LO)",
    #         "TRENTO (TN)",
    #         "VERONA (VR)",
    #         "VICENZA (VI)",
    #         "BELLUNO (BL)",
    #         "TREVISO (TV)",
    #         "VENEZIA (VE)",
    #         "PADOVA (PD)",
    #         "ROVIGO (RO)",
    #     ]
    #     client_birth_place = random.choice(cities_array)
    if re.match("^[A-Za-z `]+$", message.text.upper()) is not None or is_deutsch(
        message.text
    ):
        client_birth_place = message.text
    if client_birth_place is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(back_button)
        question_message_id = (
            await message.answer(
                text="❌Введите город рождения в правильном формате.\n"
                "<i>Формат ввода: Название города, например HEINSBERG </i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл место рождения")
        await state.update_data(client_birth_place=upper_case(client_birth_place))
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_rfid_input(message, state)


async def id_client_rfid_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(types.KeyboardButton(text="Сгенерировать"))
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите номер карты (6 цифр)✏️\n",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_client_rfid.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_client_rfid
)
async def id_client_rfid_validate(message: types.Message, state: FSMContext):
    client_rfid = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if message.text == "Сгенерировать":
        client_rfid = str(random.randint(100000, 999999))
    elif re.match("^[0-9]{6}$", message.text) is not None:
        client_rfid = message.text

    if client_rfid is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(types.KeyboardButton(text="Сгенерировать"), back_button)
        question_message_id = (
            await message.answer(
                text="❌Введите номер карты в правильном формате.\n"
                "<i>Формат ввода: 6 цифр.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл номер карты")
        await state.update_data(client_rfid=client_rfid)
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_color_of_eyes_input(message, state)


async def id_client_color_of_eyes_input(message: types.Message, state: FSMContext):
    await sqlite_db.sql_add_country_user(message.from_user.id, "de_id")
    await state.update_data(type="id")
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(
        types.KeyboardButton("GRÜN"),
        types.KeyboardButton("BLAU"),
        types.KeyboardButton("BRAUN"),
        types.KeyboardButton("GRAU"),
    ).row(back_button)
    question_message_id = (
        await message.answer(
            "Введите цвет глаз✏️\n",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_color_of_eyes.set()


@dp.message_handler(
    lambda message: "Назад◀️" not in message.text, state=FSM_DE_ID.de_color_of_eyes
)
async def id_color_of_eyes_validate(message: types.Message, state: FSMContext):
    client_color_of_eyes = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match("^[A-Za-z `]+$", message.text) is not None or is_deutsch(message.text):
        client_color_of_eyes = message.text
    if client_color_of_eyes is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(
            types.KeyboardButton("GRÜN"),
            types.KeyboardButton("BLAU"),
            types.KeyboardButton("BRAUN"),
            types.KeyboardButton("GRAU"),
        ).row(back_button)
        question_message_id = (
            await message.answer(
                text="❌Введите цвет глаз в правильном формате.\n"
                "<i>Формат ввода: только латинские буквы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл цвет глаз")
        await state.update_data(client_color_of_eyes=upper_case(client_color_of_eyes))
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_emission_date_input(message, state)


async def id_client_emission_date_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите дату выдачи✏️\n<i>Формат ввода: дд.мм.гггг</i>\nДата не ранее 01.11.2010!",
            parse_mode=ParseMode.HTML,
            reply_markup=back_kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_emission_date.set()


@dp.message_handler(
    lambda message: "Назад◀️" not in message.text, state=FSM_DE_ID.de_emission_date
)
async def id_client_emission_date_validate(message: types.Message, state: FSMContext):
    client_emission_date = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if re.match(r"^\d{2}\.\d{2}\.\d{4}$", message.text) is not None and compare_date(
        "01.11.2010", message.text
    ):
        client_emission_date = message.text
    if client_emission_date is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите дату выдачи в правильном формате.\n"
                "<i>Формат ввода: дд.мм.гггг</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл дату выдачи")
        await state.update_data(client_emission_date=client_emission_date)
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_emission_city_input(message, state)


async def id_client_emission_city_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите город выдачи✏️\n<i>Формат ввода: название города выдачи.</i>\n",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_authority.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_authority
)
async def id_client_emission_city_validate(message: types.Message, state: FSMContext):
    client_emission_city = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    # if message.text == "Сгенерировать":
    #     cities_array = [
    #         "TORINO (TO)",
    #         "VERCELLI (VC)",
    #         "NOVARA (NV)",
    #         "CUNEO (CN)",
    #         "ASTI (AT)",
    #         "ALESSANDRIA (AL)",
    #         "BIELLA (BI)",
    #         "VARESE (VA)",
    #         "COMO (CO)",
    #         "SONDRIO (SO)",
    #         "MILANO (MI)",
    #         "BERGAMO (BG)",
    #         "BRESCIA (BS)",
    #         "PAVIA (PV)",
    #         "CREMONA (CR)",
    #         "MANTOVA (MN)",
    #         "LECCO (LC)",
    #         "LODI (LO)",
    #         "TRENTO (TN)",
    #         "VERONA (VR)",
    #         "VICENZA (VI)",
    #         "BELLUNO (BL)",
    #         "TREVISO (TV)",
    #         "VENEZIA (VE)",
    #         "PADOVA (PD)",
    #         "ROVIGO (RO)",
    #     ]
    #     client_emission_city = random.choice(cities_array)
    if re.match(r"^[A-Za-z `]+$", message.text.upper()) is not None or is_deutsch(
        message.text
    ):
        client_emission_city = message.text

    if client_emission_city is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(back_button)
        question_message_id = (
            await message.answer(
                text="❌Введите город выдачи в правильном формате.\n"
                "<i>Формат ввода: название города выдачи (латинские буквы).",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл город выдачи")
        await state.update_data(client_emission_city=upper_case(client_emission_city))
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_index_input(message, state)


async def id_client_index_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(types.KeyboardButton(text="Сгенерировать"))
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите индекс (5 цифр)✏️\n", parse_mode=ParseMode.HTML, reply_markup=kb
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_client_idex.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_client_idex
)
async def id_client_index_validate(message: types.Message, state: FSMContext):
    client_index = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if message.text == "Сгенерировать":
        client_index = str(random.randint(10115, 14199))
    elif re.match("^[0-9]{5}$", message.text) is not None:
        client_index = message.text

    if client_index is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(back_button)
        question_message_id = (
            await message.answer(
                text="❌Введите индекс в правильном формате.\n"
                "<i>Формат ввода: 5 цифр.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл номер rfid")
        await state.update_data(client_index=client_index)
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_city_input(message, state)


async def id_client_city_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите город✏️\n"
            "<i>Формат ввода: название города проживания.\n"
            "Пример: TORINO.</i>",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_client_city.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_client_city
)
async def id_client_city_validate(message: types.Message, state: FSMContext):
    client_city = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    # if message.text == "Сгенерировать":
    #     cities_array = [
    #         "TORINO (TO)",
    #         "VERCELLI (VC)",
    #         "NOVARA (NV)",
    #         "CUNEO (CN)",
    #         "ASTI (AT)",
    #         "ALESSANDRIA (AL)",
    #         "BIELLA (BI)",
    #         "VARESE (VA)",
    #         "COMO (CO)",
    #         "SONDRIO (SO)",
    #         "MILANO (MI)",
    #         "BERGAMO (BG)",
    #         "BRESCIA (BS)",
    #         "PAVIA (PV)",
    #         "CREMONA (CR)",
    #         "MANTOVA (MN)",
    #         "LECCO (LC)",
    #         "LODI (LO)",
    #         "TRENTO (TN)",
    #         "VERONA (VR)",
    #         "VICENZA (VI)",
    #         "BELLUNO (BL)",
    #         "TREVISO (TV)",
    #         "VENEZIA (VE)",
    #         "PADOVA (PD)",
    #         "ROVIGO (RO)",
    #     ]
    #     client_emission_city = random.choice(cities_array)
    if re.match("^[A-Za-z `]+$", message.text) is not None or is_deutsch(message.text):
        client_city = message.text

    if client_city is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(back_kb)
        question_message_id = (
            await message.answer(
                text="❌Введите город в правильном формате.\n"
                "<i>Формат ввода: название города \n"
                "Пример: TORINO .</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл город выдачи")
        await state.update_data(client_city=upper_case(client_city))
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_street_input(message, state)


async def id_client_street_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await message.answer(
            "Введите название улицы✏️\n",
            parse_mode=ParseMode.HTML,
            reply_markup=back_kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_client_street.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_client_street
)
async def id_client_street_validate(message: types.Message, state: FSMContext):
    client_street = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if message.text is not None:
        client_street = message.text
    if client_street is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        question_message_id = (
            await message.answer(
                text="❌Введите название улицы в правильном формате.\n"
                "<i>Формат ввода: только латинские буквы и пробелы.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=back_kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл улицу")
        await state.update_data(client_street=upper_case(str(client_street)))
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_house_input(message, state)


async def id_client_house_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите номер дома✏️\n",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_client_house.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_client_house
)
async def id_client_house_validate(message: types.Message, state: FSMContext):
    client_house = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if message.text.isdigit():
        if int(message.text) > 0:
            client_house = message.text
    if client_house is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(types.KeyboardButton(text="Пропустить"))
        question_message_id = (
            await message.answer(
                text="❌Введите номер дома в правильном формате.\n"
                "<i>Формат ввода: целое число больше 0.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл номер дома")
        await state.update_data(client_house=client_house)
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_height_input(message, state)


async def id_client_height_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
    kb.add(back_button)
    question_message_id = (
        await message.answer(
            "Введите рост в cm.✏️\n<i>Формат ввода: целое число</i>\nПример: 122",
            parse_mode=ParseMode.HTML,
            reply_markup=kb,
        )
    )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_height.set()


@dp.message_handler(
    lambda message: "️Назад ◀️" not in message.text, state=FSM_DE_ID.de_height
)
async def id_client_height_validate(message: types.Message, state: FSMContext):
    client_height = None
    await delete_user_reply(message.from_user.id, message.message_id)
    data = await state.get_data()

    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")

    if message.text.isdigit():
        if int(message.text) > 0:
            client_height = message.text
    if client_height is None:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(types.KeyboardButton(text="Пропустить"))
        question_message_id = (
            await message.answer(
                text="❌Введите рост правильном формате\n"
                "<i>Формат ввода: целое число больше 0.</i>",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        await state.update_data(question_message_id=question_message_id)
    else:
        logger.info(f"Пользователь {message.from_user.id} ввёл номер дома")
        await state.update_data(client_height=client_height)
        if "edit_mode" in data:
            return await start_generate_edit(message.from_user.id, state)
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        await id_client_holo_id_input(message, state)


async def id_client_holo_id_input(message: types.Message, state: FSMContext):
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)

    kb = types.InlineKeyboardMarkup(resize_keyboard=True)
    kb.row(
        types.InlineKeyboardButton(text="1", callback_data="holo_1"),
        types.InlineKeyboardButton(text="2", callback_data="holo_2"),
        types.InlineKeyboardButton(text="3", callback_data="holo_3"),
        types.InlineKeyboardButton(text="Не ставить", callback_data="holo_0"),
    )
    kb.add(back_button_inline)

    photo_path = f"./files/de_id/holo_choice.png"  # Замените на путь к вашей картинке
    with open(photo_path, "rb") as photo:
        question_message_id = (
            await message.answer_photo(
                photo, caption="Выберите номер голограммы:", reply_markup=kb
            )
        )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_client_holo_id.set()


@dp.callback_query_handler(
    lambda c: c.data.startswith("holo_") and "Назад ◀️" not in c.data,
    state=FSM_DE_ID.de_client_holo_id,
)
async def id_client_holo_id_validate(
    callback_query: types.CallbackQuery, state: FSMContext
):
    await dp.bot.answer_callback_query(callback_query.id)
    holo_id = int(callback_query.data.split("_")[1])
    logger.info(f"Пользователь {callback_query.from_user.id} выбрал голограмму")
    await state.update_data(client_holo_id=holo_id)

    data = await state.get_data()
    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=callback_query.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")
    if "edit_mode" in data:
        return await start_generate_edit(callback_query.from_user.id, state)
    message_to_edit_id = await data_checkup(callback_query.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    await id_client_signature_id_input(callback_query.from_user.id, state)


async def id_client_signature_id_input(user_id, state: FSMContext):
    if type(user_id) == types.Message:
        user_id = user_id.from_user.id
    message_to_edit_id = await data_checkup(user_id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    data = await state.get_data()

    process_generate_signature(user_id=user_id, data=data["sign"])

    kb = types.InlineKeyboardMarkup()
    kb.add(
        types.InlineKeyboardButton(text="1", callback_data="sig_1"),
        types.InlineKeyboardButton(text="2", callback_data="sig_2"),
        types.InlineKeyboardButton(text="3", callback_data="sig_3"),
    )
    kb.add(
        types.InlineKeyboardButton(text="4", callback_data="sig_4"),
        types.InlineKeyboardButton(text="5", callback_data="sig_5"),
        types.InlineKeyboardButton(text="6", callback_data="sig_6"),
    )
    kb.add(
        types.InlineKeyboardButton(text="Не ставить", callback_data="sig_0"),
        back_button_inline,
    )

    photo_path = f"./files/de_id/photo_usr/{user_id}_choose_signature.png"  # Замените на путь к вашей картинке
    with open(photo_path, "rb") as photo:
        question_message_id = (
            await dp.bot.send_photo(
                chat_id=user_id,
                photo=photo,
                caption="Выберите тип подписи:",
                reply_markup=kb,
            )
        )["message_id"]
    await state.update_data(question_message_id=question_message_id)
    await FSM_DE_ID.de_client_signature_id.set()


@dp.callback_query_handler(
    lambda c: c.data.startswith("sig_") and "Назад ◀️" not in c.data,
    state=FSM_DE_ID.de_client_signature_id,
)
async def id_client_signature_id_validate(
    callback_query: types.CallbackQuery, state: FSMContext
):
    await dp.bot.answer_callback_query(callback_query.id)
    signature_id = int(callback_query.data.split("_")[1])
    await state.update_data(client_signature_id=signature_id)
    logger.info(f"Пользователь {callback_query.from_user.id} выбрал подпись")
    data = await state.get_data()
    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=callback_query.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")
    if "edit_mode" in data:
        return await start_generate_edit(callback_query.from_user.id, state)
    message_to_edit_id = await data_checkup(callback_query.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    await id_client_photo_input(callback_query.from_user.id, state)


async def id_client_photo_input(user_id: int or types.Message, state: FSMContext):
    if type(user_id) == types.Message:
        user_id = user_id.from_user.id
    message_to_edit_id = await data_checkup(user_id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    question_message_id = (
        await dp.bot.send_message(
            chat_id=user_id,
            text="Загрузите фотографию 📷\n"
            " ❗️Требования к фотографии:\n"
            "➖ Фотография должна быть загружена без сжатия, нажимаем скрепку - файл - выбрать фото;\n"
            "➖ На фотографии должно быть видно плечи, глаза открыты;\n"
            "➖ Кадр должен быть в хорошем освещении;\n"
            "➖ Лицо должно быть под прямым углом к камере;\n"
            "Поддерживаемые форматы: JPG, JPEG, PNG ❗️",
            reply_markup=back_kb,
        )
    )["message_id"]
    await FSM_DE_ID.de_client_photo.set()
    await state.update_data(question_message_id=question_message_id)


@dp.message_handler(
    content_types=types.ContentType.DOCUMENT, state=FSM_DE_ID.de_client_photo
)
async def process_photo(message: types.Message, state: FSMContext):
    data = await state.get_data()
    # Check if the message has a document
    # Check if the document is in the required format (PNG)
    file_info = await dp.bot.get_file(message.document.file_id)
    await message.delete()
    if file_info.file_path.lower().endswith(".png"):
        # Download the document and save it as user_id.png
        photo_path = f"./files/de_id/photo_usr/{message.from_user.id}.png"
        await dp.bot.download_file(file_info.file_path, photo_path)
        # Check if the image has an alpha channel
        img = Image.open(photo_path).convert("RGBA")
        if img.mode == "RGBA":
            # Process the photo in a separate thread
            thread = threading.Thread(
                target=process_passport_photo, args=(message.from_user.id,)
            )
            thread.start()
            # Проверка состояния потока каждую секунду с использованием asyncio.sleep
            while thread.is_alive():
                await asyncio.sleep(1)
            # Check if the processed photo exists
            processed_photo_path = (
                f"./files/de_id/photo_usr/{message.from_user.id}_w.png"
            )
            if os.path.exists(processed_photo_path):
                data = await state.get_data()
                question_message_id = data.get("question_message_id")
                try:
                    await dp.bot.delete_message(
                        chat_id=message.chat.id, message_id=question_message_id
                    )
                    message_to_edit_id = await data_checkup(message.from_user.id, state)
                    await dp.bot.delete_message(
                        chat_id=message.chat.id, message_id=message_to_edit_id
                    )
                except:
                    pass
                logger.info(f"Пользователь {message.from_user.id} отправил фотографию")
                await id_size_input(message, state)
    elif file_info.file_path.lower().endswith(".jpg"):
        # Download the document and save it as user_id.png
        photo_path = f"./files/de_id/photo_usr/{message.from_user.id}.png"
        await dp.bot.download_file(
            file_info.file_path, f"./files/de_id/photo_usr/{message.from_user.id}.jpg"
        )
        # AI work

        from rembg import remove

        out = remove(
            Image.open(f"./files/de_id/photo_usr/{message.from_user.id}.jpg"),
            True,
            240,
            240,
        )
        out = out.convert("RGBA")
        out.save(f"./files/de_id/photo_usr/{message.from_user.id}.png")
        # Check if the image has an alpha channel
        img = Image.open(photo_path).convert("RGBA")
        if img.mode == "RGBA":
            # Process the photo in a separate thread
            thread = threading.Thread(
                target=process_passport_photo, args=(message.from_user.id,)
            )
            thread.start()
            # Проверка состояния потока каждую секунду с использованием asyncio.sleep
            while thread.is_alive():
                await asyncio.sleep(1)
            # Check if the processed photo exists
            processed_photo_path = (
                f"./files/de_id/photo_usr/{message.from_user.id}_w.png"
            )
            if os.path.exists(processed_photo_path):
                data = await state.get_data()
                question_message_id = data.get("question_message_id")
                try:
                    await dp.bot.delete_message(
                        chat_id=message.chat.id, message_id=question_message_id
                    )
                    message_to_edit_id = await data_checkup(message.from_user.id, state)
                    await dp.bot.delete_message(
                        chat_id=message.chat.id, message_id=message_to_edit_id
                    )
                except:
                    pass
                logger.info(f"Пользователь {message.from_user.id} отправил фотографию")
                await id_size_input(message, state)
    elif file_info.file_path.lower().endswith(".jpeg"):
        # Download the document and save it as user_id.png
        photo_path = f"./files/de_id/photo_usr/{message.from_user.id}.png"
        await dp.bot.download_file(
            file_info.file_path, f"./files/de_id/photo_usr/{message.from_user.id}.jpeg"
        )
        # AI work

        from rembg import remove

        out = remove(
            Image.open(f"./files/de_id/photo_usr/{message.from_user.id}.jpeg"),
            True,
            240,
            240,
        )
        out = out.convert("RGBA")
        out.save(f"./files/de_id/photo_usr/{message.from_user.id}.png")
        # Check if the image has an alpha channel
        img = Image.open(photo_path).convert("RGBA")
        if img.mode == "RGBA":
            # Process the photo in a separate thread
            thread = threading.Thread(
                target=process_passport_photo, args=(message.from_user.id,)
            )
            thread.start()
            # Проверка состояния потока каждую секунду с использованием asyncio.sleep
            while thread.is_alive():
                await asyncio.sleep(1)
            # Check if the processed photo exists
            processed_photo_path = (
                f"./files/de_id/photo_usr/{message.from_user.id}_w.png"
            )
            if os.path.exists(processed_photo_path):
                data = await state.get_data()
                question_message_id = data.get("question_message_id")
                try:
                    await dp.bot.delete_message(
                        chat_id=message.chat.id, message_id=question_message_id
                    )
                    message_to_edit_id = await data_checkup(message.from_user.id, state)
                    await dp.bot.delete_message(
                        chat_id=message.chat.id, message_id=message_to_edit_id
                    )
                except:
                    pass
                logger.info(f"Пользователь {message.from_user.id} отправил фотографию")
                await id_size_input(message, state)
            else:
                await dp.bot.send_message(
                    chat_id=message.chat.id,
                    text="❌ Фотография не соответствует требованиям.\n"
                    "ИИ не смог обработать вашу фотографию.\n"
                    "Это происходит, если фото не соответствует требованиям, "
                    "проверьте что расширение файла PNG, "
                    "либо загрузите другое изображение.",
                )
        else:
            await dp.bot.send_message(
                chat_id=message.chat.id,
                text="❌ Фотография не соответствует требованиям.\n"
                "ИИ не смог обработать вашу фотографию.\n"
                "Это происходит, если фото не соответствует требованиям, "
                "проверьте что расширение файла PNG, "
                "либо загрузите другое изображение.",
            )
    else:
        await dp.bot.send_message(
            chat_id=message.chat.id,
            text="❌ Фотография не соответствует требованиям.\n"
            "ИИ не смог обработать вашу фотографию.\n"
            "Это происходит, если фото не соответствует требованиям, "
            "проверьте что расширение файла PNG, "
            "либо загрузите другое изображение.",
        )


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM_DE_ID.de_client_photo
)
async def process_photo_nontype(message: types.Message, state: FSMContext):
    await message.delete()
    await message.answer(
        "Вы должны отправить фотографию без фона в формате PNG и без сжатия."
    )


@dp.message_handler(
    content_types=types.ContentType.PHOTO, state=FSM_DE_ID.de_client_photo
)
async def process_photo_nontype_photo(message: types.Message, state: FSMContext):
    await message.delete()
    await message.answer(
        "Вы должны отправить фотографию без фона в формате PNG и без сжатия."
    )


async def id_size_input(user_id: int or types.Message, state: FSMContext):
    if type(user_id) == types.Message:
        user_id = user_id.from_user.id
    message_to_edit_id = await data_checkup(user_id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    kb = types.ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
    kb.add(types.KeyboardButton(text="📃На листе А4"))
    kb.add(types.KeyboardButton(text="🪪В размер документа"))
    kb.add(back_button)
    question_message_id = (
        await dp.bot.send_message(
            chat_id=user_id, text="Выберите размер документа", reply_markup=kb
        )
    )["message_id"]
    await FSM_DE_ID.de_size.set()
    await state.update_data(question_message_id=question_message_id)


@dp.message_handler(
    lambda message: "Назад ◀️" not in message.text, state=FSM_DE_ID.de_size
)
async def id_select_size_validate(message: types.Message, state: FSMContext):
    if message.text == "📃На листе А4":
        size_type = "A4"
    elif message.text == "🪪В размер документа":
        size_type = "DOC"
    else:
        message_to_edit_id = await data_checkup(message.from_user.id, state)
        await state.update_data(message_to_edit_id=message_to_edit_id)
        kb = types.ReplyKeyboardMarkup(resize_keyboard=True)
        kb.add(types.KeyboardButton(text="📃На листе А4"))
        kb.add(types.KeyboardButton(text="🪪В размер документа"))
        question_message_id = (
            await message.answer(
                text="❌Выберите тип через клавиатуру.\n",
                parse_mode=ParseMode.HTML,
                reply_markup=kb,
            )
        )["message_id"]
        return await state.update_data(question_message_id=question_message_id)
    await message.delete()
    await state.update_data(size=size_type)
    logger.info(f"Пользователь {message.from_user.id} выбрал размер документа")
    data = await state.get_data()
    if "question_message_id" in data:
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=data["question_message_id"]
        )
    else:
        logger.warning("question_message_id not found in state data")
    if "edit_mode" in data:
        return await start_generate_edit(message.from_user.id, state)
    message_to_edit_id = await data_checkup(message.from_user.id, state)
    await state.update_data(message_to_edit_id=message_to_edit_id)
    await start_generate(message, state)


async def start_generate(message: types.Message, state: FSMContext):
    message_to_delete = await message.answer("Ожидайте генерируется...")
    data = await state.get_data()
    logger.info(f"Начинаем генерацию документа для пользователя {message.from_user.id}")
    result_queue = queue.Queue()
    id_thread = threading.Thread(
        target=generate_id, args=(data, message.from_user.id, result_queue)
    )
    id_thread.start()
    id_thread.join()
    result = result_queue.get()
    if "Error" in result:
        logger.error(
            f"Ошибка при генерации документа для пользователя {message.from_user.id}:\n{result}"
        )
        await message.answer("❌Ошибка при генерации изображения")
        await dp.bot.send_message(chat_id=message.from_user.id, text=result)
    else:
        logger.info(
            f"Успешно завершили генерацию документа для пользователя {message.from_user.id}"
        )
        await dp.bot.delete_message(
            chat_id=message.from_user.id, message_id=message_to_delete["message_id"]
        )
        with open(result + "_wm.png", "rb") as photo:
            await dp.bot.send_document(chat_id=message.from_user.id, document=photo)
            await message.answer(
                "Завершите покупку документа.", reply_markup=client_kb.kb_de_finish_id
            )


async def start_generate_edit(user_id: int, state: FSMContext):
    message_to_delete = await dp.bot.send_message(
        chat_id=user_id, text="Ожидайте генерируется..."
    )
    data = await state.get_data()
    result_queue = queue.Queue()
    id_thread = threading.Thread(target=generate_id, args=(data, user_id, result_queue))
    id_thread.start()
    id_thread.join()
    result = result_queue.get()
    if "Error" in result:
        await dp.bot.send_message(
            chat_id=user_id, text="❌Ошибка при генерации изображения"
        )
        await dp.bot.send_message(chat_id=363661148, text=result)
    else:
        await dp.bot.delete_message(
            chat_id=user_id, message_id=message_to_delete["message_id"]
        )
        with open(result + "_wm.png", "rb") as photo:
            await dp.bot.send_document(chat_id=user_id, document=photo)
            await dp.bot.send_message(
                chat_id=user_id,
                text="Завершите покупку документа.",
                reply_markup=client_kb.kb_de_finish_id,
            )


@dp.callback_query_handler(text="de_change_id", state="*")
async def de_change_id(call: types.CallbackQuery, state: FSMContext):
    kb = types.ReplyKeyboardMarkup(one_time_keyboard=True)
    await call.message.delete()
    for field in data_fields:
        kb.add(types.KeyboardButton(text=f'{field["title"]}'))
    edit_message_to_delete_id = (
        await call.message.answer(
            text="Выберите параметр, который хотите изменить", reply_markup=kb
        )
    )["message_id"]
    await state.update_data(edit_message_to_delete_id=edit_message_to_delete_id)
    await FSM_DE_ID.de_edit_data.set()


@dp.message_handler(state=FSM_DE_ID.de_edit_data)
async def edit_field(message: types.Message, state: FSMContext):
    data = await state.get_data()
    await dp.bot.delete_message(
        chat_id=message.from_user.id, message_id=int(data["edit_message_to_delete_id"])
    )
    await message.delete()
    for field in data_fields:
        if field["title"] == message.text:
            key = field["key"]
    await state.update_data(edit_mode=1)
    func_name = key
    func_name_with_input = "id_" + func_name + "_input"

    # Получаем ссылку на функцию с использованием имени и вызываем ее
    function_to_call = globals()[func_name_with_input]
    await function_to_call(message, state)


@dp.callback_query_handler(text="de_pay_id", state="*")
async def command_pay_it_bill(callback: types.CallbackQuery, state: FSMContext):
    await state.finish()
    await state.update_data(pay_country="de_id")
    await client.command_promo_quest(callback, state)


from handlers.users.generate.de_country.de_country_menu import create_germany

state_input_functions = {
    "FSM_DE_ID:de_first_name": create_germany,
    "FSM_DE_ID:de_last_name": id_client_first_name_input,
    "FSM_DE_ID:de_maiden_name": id_client_last_name_input,
    "FSM_DE_ID:de_client_id": id_client_maiden_name_input,
    "FSM_DE_ID:de_birth_date": id_client_id_input,
    "FSM_DE_ID:de_sex": id_client_birth_date_input,
    "FSM_DE_ID:de_nationality": id_client_sex_input,
    "FSM_DE_ID:de_birth_place": id_client_nationality_input,
    "FSM_DE_ID:de_client_rfid": id_client_birth_place_input,
    "FSM_DE_ID:de_color_of_eyes": id_client_rfid_input,
    "FSM_DE_ID:de_emission_date": id_client_color_of_eyes_input,
    "FSM_DE_ID:de_authority": id_client_emission_date_input,
    "FSM_DE_ID:de_client_idex": id_client_emission_city_input,
    "FSM_DE_ID:de_client_city": id_client_index_input,
    "FSM_DE_ID:de_client_street": id_client_city_input,
    "FSM_DE_ID:de_client_house": id_client_street_input,
    "FSM_DE_ID:de_client_holo_id": id_client_house_input,
    "FSM_DE_ID:de_client_signature_id": id_client_holo_id_input,
    "FSM_DE_ID:de_client_photo": id_client_signature_id_input,
    "FSM_DE_ID:de_size": id_client_photo_input,
}


@dp.message_handler(lambda message: message.text == "️Назад ◀️", state=FSM_DE_ID)
async def go_back(message: types.Message, state: FSMContext):
    current_state = str(await state.get_state())
    print(current_state)
    if current_state in state_input_functions:
        input_function = state_input_functions[current_state]
        await input_function(
            message, state
        )  # вызов функции ввода для предыдущего состояния
    else:
        await message.answer("Unknown state.")


@dp.callback_query_handler(lambda call: call.data == "️Назад ◀️", state="*")
async def go_back(call: types.CallbackQuery, state: FSMContext):
    await call.message.delete()
    current_state = str(await state.get_state())
    print(current_state)
    if current_state in state_input_functions:
        input_function = state_input_functions[current_state]
        await input_function(
            call.message, state
        )  # вызов функции ввода для предыдущего состояния
    else:
        await call.message.answer("Unknown state.")


def generate_id(data, user_id, result_queue):
    try:
        import datetime
        import random

        import codicefiscale as codicefiscale
        from dateutil.relativedelta import relativedelta
        from mrz.generator.td1 import TD1CodeGenerator
        from PIL import Image, ImageDraw, ImageEnhance, ImageFilter, ImageFont

        """
        Переменные текста
        """
        # id_client = data["client_id"]
        first_name = data["client_first_name"]
        last_name = data["client_last_name"]
        maiden_name = data["client_maiden_name"]
        birth_date = data["client_birth_date"]
        nationality = data["client_nationality"]
        birth_city = data["client_birth_place"]
        issue_date = data["client_emission_date"]
        expire_date = datetime.datetime.strftime(
            datetime.datetime.strptime(issue_date, "%d.%m.%Y")
            + relativedelta(years=10)
            - relativedelta(days=1),
            "%d.%m.%Y",
        )
        signature_id = data["client_signature_id"]
        rfid = data["client_rfid"]
        holo_id = data["client_holo_id"]
        client_id = data["client_id"]
        color_eyes = data["client_color_of_eyes"]
        height = random.randint(170, 185)
        emisson_place = data["client_emission_city"]
        index = data["client_index"]
        city = data["client_city"]
        street = data["client_street"]
        house = data["client_house"]
        sex = data["client_sex"]

        background = Image.open("./files/de_id/front.png").resize((1016, 638))
        photo_face = (
            Image.open(f"./files/de_id/photo_usr/{user_id}_w.png")
            .convert("RGBA")
            .resize((367, 484))
        )
        background.paste(photo_face, (47, 129), photo_face)

        text_layer = Image.new("RGBA", background.size, (0, 0, 0, 0))
        draw = ImageDraw.Draw(text_layer)
        font = ImageFont.truetype("./fonts/germany_id/Germany_doc-Regular.otf", 38)

        if str(maiden_name).capitalize() != "Пропустить":
            draw.text((466, 90), str(last_name), (0, 0, 0), font)
            draw.text((466, 130), str(maiden_name), (0, 0, 0), font)
        else:
            draw.text((466, 114), str(last_name), (0, 0, 0), font)
        draw.text((467, 205), str(first_name), (0, 0, 0), font)
        draw.text((469, 293), str(birth_date), (0, 0, 0), font)
        draw.text((694, 294), str(nationality), (0, 0, 0), font)
        draw.text((468, 366), str(birth_city), (0, 0, 0), font)
        draw.text((469, 448), str(expire_date), (0, 0, 0), font)
        font = ImageFont.truetype("./fonts/germany_id/OCRB10PitchBT-Regular.otf", 38)
        draw.text((779, 436), str(rfid), (0, 0, 0), font)
        font = ImageFont.truetype("./fonts/germany_id/OCRB10PitchBT-Regular.otf", 45)
        draw.text((724, 23), str(client_id).upper(), (0, 0, 0), font)

        sign = data["sign"].capitalize()
        if int(signature_id) != 0:
            fonts_dict = {
                1: ImageFont.truetype(f"./fonts/1.ttf", size=118),
                2: ImageFont.truetype(f"./fonts/2.ttf", size=88),
                3: ImageFont.truetype(f"./fonts/3.ttf", size=118),
                4: ImageFont.truetype(f"./fonts/4.ttf", size=78),
                5: ImageFont.truetype(f"./fonts/5.ttf", size=88),
                6: ImageFont.truetype(f"./fonts/6.ttf", size=45),
                7: ImageFont.truetype(f"./fonts/66.ttf", size=68),
            }
            if int(signature_id) == 6:
                x, y = 496, 572
                draw.text(
                    xy=(x, y),
                    text=sign,
                    font=ImageFont.truetype("./fonts/6.ttf", 45),
                    fill=(0, 0, 0, 250),
                    stroke_width=0,
                    anchor="lm",
                )
                fnt66 = ImageFont.truetype(f"./fonts/66.ttf", size=50)
                draw.text(xy=(501, 577), text=f"k", font=fnt66, fill="#000000")
            else:
                font = fonts_dict[signature_id]
                x, y = 496, 572
                draw.text(
                    xy=(x, y),
                    text=sign,
                    font=font,
                    fill=(0, 0, 0, 250),
                    stroke_width=0,
                    anchor="lm",
                )

        text_layer = text_layer.filter(ImageFilter.GaussianBlur(0.6))
        background.paste(text_layer, (0, 0), text_layer)

        if int(holo_id) != 0:
            if int(holo_id) == 3:
                from PIL import Image

                image_file = Image.open(
                    f"./files/de_id/photo_usr/{user_id}_w.png"
                ).resize(
                    (367, 484)
                )  # open colour image
                Imagos = Image.new("RGB", image_file.size, (255, 255, 255))
                Imagos.paste(image_file, (0, 0), image_file)
                thresh = 95
                fn = lambda x: 255 if x > thresh else 0
                r = Imagos.convert("L").point(fn, mode="1")
                mask = r
                imagekok = (
                    Image.open("./files/de_id/eagle_hologram.png")
                    .convert("RGBA")
                    .resize((367, 484))
                )
                imagekok.putalpha(255)

                mask = mask.resize(imagekok.size)

                ok = Image.new("RGBA", imagekok.size, (0, 0, 0, 0))
                ok.paste(imagekok, (0, 0), mask)
                ok.save(f"./files/de_id/zagotovka{user_id}.png")

                ok1 = Image.open(f"./files/de_id/zagotovka{user_id}.png").resize(
                    (358, 541)
                )
                datas = ok1.getdata()
                newData = []
                for item in datas:
                    if item[0] == 0 and item[1] == 0 and item[2] == 0:
                        item = list(item)
                        item[3] = 0
                        item = tuple(item)
                        newData.append(item)

                    elif item[3] != 0:
                        item = list(item)
                        item[3] = 20
                        item = tuple(item)
                        newData.append(item)
                    else:
                        newData.append(item)
                ok1.putdata(newData)
                background.paste(ok1, (390, 70), ok1)
                # background.paste(holo1,(400,0),mask)

                ok1 = Image.open("./files/de_id/eagle (2).png").resize((1000, 630))
                datas = ok1.getdata()
                newData = []
                for item in datas:
                    if item[3] != 0:
                        item = list(item)
                        item[3] = 10
                        item = tuple(item)
                        newData.append(item)
                    else:
                        newData.append(item)
                ok1.putdata(newData)
                background.paste(ok1, (0, 0), ok1)

                from PIL import Image, ImageChops

                # creating a image1 object
                im1 = Image.open("./files/de_id/eagle (2).png").resize((1000, 630))

                # creating a image2 object
                im2 = Image.open("./files/de_id/eagle (2).png").resize((1000, 630))

                # applying lighter method
                im3 = ImageChops.lighter(im1, im2)
                sm = Image.new("RGBA", im3.size, (0, 0, 0, 0))
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)

                sm.save(f"./files/de_id/HoloJ{user_id}.png")
                alkok = Image.new("RGBA", sm.size, (0, 0, 0, 0))
                alkok.save(f"./files/de_id/HoloM{user_id}.png")

                overlay_image = Image.open(f"./files/de_id/HoloJ{user_id}.png").convert(
                    "RGBA"
                )
                # Изменение прозрачности
                alpha_value = 60
                alpha = overlay_image.getchannel("A").point(
                    lambda i: i * alpha_value / 255
                )
                overlay_image.putalpha(alpha)
                # Измените размер verlay_image
                new_size = (1000, 630)  # Замените width и height на нужные значения
                overlay_image = overlay_image.resize(new_size, Image.LANCZOS)
                # aksak = Image.open("C:/Users/Моё/Downloads/image.png").convert('RGBA')
                background.paste(overlay_image, (0, 0), overlay_image)
            if int(holo_id) == 2:
                ok1 = Image.open("./files/de_id/eagle (2).png").resize((1000, 630))
                datas = ok1.getdata()
                newData = []
                for item in datas:
                    if item[3] != 0:
                        item = list(item)
                        item[3] = 10
                        item = tuple(item)
                        newData.append(item)
                    else:
                        newData.append(item)
                ok1.putdata(newData)
                background.paste(ok1, (0, 0), ok1)

                from PIL import Image, ImageChops

                # creating a image1 object
                im1 = Image.open("./files/de_id/eagle (2).png").resize((1000, 630))

                # creating a image2 object
                im2 = Image.open("./files/de_id/eagle (2).png").resize((1000, 630))

                # applying lighter method
                im3 = ImageChops.lighter(im1, im2)
                sm = Image.new("RGBA", im3.size, (0, 0, 0, 0))
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)
                sm.paste(im3, (0, 0), im3)

                sm.save(f"./files/de_id/HoloJ{user_id}.png")
                alkok = Image.new("RGBA", sm.size, (0, 0, 0, 0))
                alkok.save(f"./files/de_id/HoloM{user_id}.png")

                overlay_image = Image.open(f"./files/de_id/HoloJ{user_id}.png").convert(
                    "RGBA"
                )
                # Изменение прозрачности
                alpha_value = 60
                alpha = overlay_image.getchannel("A").point(
                    lambda i: i * alpha_value / 255
                )
                overlay_image.putalpha(alpha)
                # Измените размер verlay_image
                new_size = (1000, 630)  # Замените width и height на нужные значения
                overlay_image = overlay_image.resize(new_size, Image.LANCZOS)
                # aksak = Image.open("C:/Users/Моё/Downloads/image.png").convert('RGBA')
                background.paste(overlay_image, (0, 0), overlay_image)

                font = ImageFont.truetype(
                    "./fonts/germany_id/OCRB10PitchBT-Regular.otf", 42
                )
                draw.text(
                    (750, 79),
                    str(client_id).upper(),
                    fill=(70, 207, 100, 140),
                    font=font,
                )
            if int(holo_id) == 1:
                from PIL import Image

                image_file = Image.open(
                    f"./files/de_id/photo_usr/{user_id}_w.png"
                ).resize(
                    (367, 484)
                )  # open colour image
                Imagos = Image.new("RGB", image_file.size, (255, 255, 255))
                Imagos.paste(image_file, (0, 0), image_file)
                thresh = 95
                fn = lambda x: 255 if x > thresh else 0
                r = Imagos.convert("L").point(fn, mode="1")
                mask = r
                imagekok = (
                    Image.open("./files/de_id/eagle_hologram.png")
                    .convert("RGBA")
                    .resize((367, 484))
                )
                imagekok.putalpha(255)

                mask = mask.resize(imagekok.size)

                ok = Image.new("RGBA", imagekok.size, (0, 0, 0, 0))
                ok.paste(imagekok, (0, 0), mask)
                ok.save(f"./files/de_id/zagotovka{user_id}.png")

                ok1 = Image.open(f"./files/de_id/zagotovka{user_id}.png").resize(
                    (358, 541)
                )
                datas = ok1.getdata()
                newData = []
                for item in datas:
                    if item[0] == 0 and item[1] == 0 and item[2] == 0:
                        item = list(item)
                        item[3] = 0
                        item = tuple(item)
                        newData.append(item)

                    elif item[3] != 0:
                        item = list(item)
                        item[3] = 20
                        item = tuple(item)
                        newData.append(item)
                    else:
                        newData.append(item)
                ok1.putdata(newData)
                background.paste(ok1, (390, 70), ok1)
                # background.paste(holo1,(400,0),mask)
        else:
            pass

        background_second = Image.open("./files/de_id/back.png")
        text_layer_back = Image.new("RGBA", background_second.size, (0, 0, 0, 0))
        draw_back = ImageDraw.Draw(text_layer_back)
        font = ImageFont.truetype("./fonts/germany_id/Germany_doc-Regular.otf", 38)
        draw_back.text((45, 38), str(color_eyes), (0, 0, 0), font)
        draw_back.text((45, 98), f"{height} cm", (0, 0, 0), font)
        draw_back.text(
            (45, 158),
            f"{str(issue_date).split('.')[0]}.{str(issue_date).split('.')[1]}.{str(issue_date).split('.')[2][2:4]}",
            (0, 0, 0),
            font,
        )

        from textwrap import fill

        if len(str(emisson_place)) >= 20:
            draw_back.text(
                xy=(38, 238),
                text=str(fill(emisson_place, width=20).split("\n")[0]),
                font=ImageFont.truetype(
                    "./fonts/germany_id/Germany_doc-Regular.otf", 28
                ),
                fill=(0, 0, 0, 255),
                stroke_width=0,
                anchor="lm",
            )
            draw_back.text(
                xy=(38, 259),
                text=str(fill(emisson_place, width=20).split("\n")[1]),
                font=ImageFont.truetype(
                    "./fonts/germany_id/Germany_doc-Regular.otf", 28
                ),
                fill=(0, 0, 0, 255),
                stroke_width=0,
                anchor="lm",
            )
        else:
            draw_back.text(
                xy=(38, 238),
                text=emisson_place,
                font=ImageFont.truetype(
                    "./fonts/germany_id/Germany_doc-Regular.otf", 28
                ),
                fill=(0, 0, 0, 255),
                stroke_width=0,
                anchor="lm",
            )

        # Откройте другое изображение
        overlay_image_back = Image.open(
            f"./files/de_id/photo_usr/{user_id}_w.png"
        ).convert("LA")
        # Изменение прозрачности
        alpha_value_back = 110
        alpha_back = overlay_image_back.getchannel("A").point(
            lambda i: i * alpha_value_back / 255
        )
        overlay_image_back.putalpha(alpha_back)
        # Измените размер verlay_image
        new_size = (75, 75)  # Замените width и height на нужные значения
        overlay_image_back = overlay_image_back.resize(new_size, Image.LANCZOS)
        overlay_position = (
            288,
            110,
        )  # координаты x, y для вставки обрезанного изображения
        # Вставьте overlay_image на image с использованием альфа-канала
        overlay_image_back = overlay_image_back.filter(ImageFilter.GaussianBlur(2))
        background_second.paste(
            overlay_image_back, overlay_position, overlay_image_back
        )

        font = ImageFont.truetype("./fonts/germany_id/OCRB10PitchBT-Regular.otf", 28)
        draw_back.text(
            (258, 140),
            f"{str(issue_date).split('.')[0]}.{str(issue_date).split('.')[1]}.{str(issue_date).split('.')[2][2:4]}",
            fill=(22, 22, 22, 40),
            font=font,
        )

        font = ImageFont.truetype("./fonts/germany_id/Germany_doc-Regular.otf", 28)
        draw_back.text((460, 40), f"{index} {city}", (0, 0, 0), font)
        draw_back.text((460, 68), f"{street} {house}", (0, 0, 0), font)

        # Задайте все необходимые данные
        document_type = "ID"  # Тип документа для итальянской ID-карты
        surname = de_transliterate(str(last_name))
        given_names = de_transliterate(str(first_name))
        document_number = str(client_id)
        nationality = "D"

        birth_datemrz = f"{birth_date.split('.')[2][2::]}{birth_date.split('.')[1]}{birth_date.split('.')[0]}"
        expiremrz = f"{expire_date.split('.')[2][2::]}{expire_date.split('.')[1]}{expire_date.split('.')[0]}"

        from mrz.generator.td1 import TD1CodeGenerator

        # Создайте генератор кода MRZ
        td1_generator = TD1CodeGenerator(
            document_type=document_type,
            country_code="D",
            document_number=document_number,
            birth_date=birth_datemrz,
            sex=sex,
            expiry_date=expiremrz,
            nationality=nationality,
            surname=surname,
            given_names=given_names,
        )

        x, y = 64, 440
        draw_back.text(
            xy=(x, y),
            text=str(str(td1_generator).split("\n")[0]),
            font=ImageFont.truetype(f"./fonts/es_OCR-B 10 BT.ttf", 48),
            fill=(12, 12, 12, 255),
            stroke_width=0,
            anchor="lm",
        )
        x, y = 64, 480
        draw_back.text(
            xy=(x, y),
            text=str(str(td1_generator).split("\n")[1]),
            font=ImageFont.truetype(f"./fonts/es_OCR-B 10 BT.ttf", 48),
            fill=(12, 12, 12, 255),
            stroke_width=0,
            anchor="lm",
        )
        x, y = 64, 520
        draw_back.text(
            xy=(x, y),
            text=str(str(td1_generator).split("\n")[2]),
            font=ImageFont.truetype(f"./fonts/es_OCR-B 10 BT.ttf", 48),
            fill=(12, 12, 12, 255),
            stroke_width=0,
            anchor="lm",
        )

        x, y = 410, 355
        print(str("<<" + str(td1_generator).split("\n")[2]))
        for letter in str("<<" + str(td1_generator).split("\n")[2]):
            draw_back.text(
                xy=(x, y),
                text=letter,
                font=ImageFont.truetype(f"./fonts/es_OCR-B 10 BT.ttf", 22),
                fill=(240, 240, 240, 100),
                stroke_width=0,
                anchor="lm",
            )
            x += 18

        text_layer_back = text_layer_back.filter(ImageFilter.GaussianBlur(0.7))

        white = Image.new("RGBA", background_second.size, (255, 255, 255))
        white.paste(background_second, (0, 0))
        white.paste(text_layer_back, (0, 0), text_layer_back)

        # 6. Объедините исходное изображение и новый слой с помощью `Image.alpha_composite()`
        # image = Image.alpha_composite(image, overlay_layer)
        image_name = f"./files/de_id/photo_usr/{user_id}_completed"
        if data["size"] == "DOC":
            bg = Image.new("RGB", (1012 * 2 + 10, 638), (255, 255, 255))
            bg.paste(background, box=(0, 0), mask=background)
            bg.paste(white, box=((1012 + 10), 0), mask=white)
            bg.save(image_name + ".png")
            result_queue.put(image_name)
        elif data["size"] == "A4":
            bg = Image.new("RGB", (2481, 3507), (255, 255, 255))
            bg_front = background.rotate(
                random.uniform(-0.9, 0.9), resample=Image.BICUBIC, expand=True
            )
            bg_back = white.rotate(
                random.uniform(-0.9, 0.9), resample=Image.BICUBIC, expand=True
            )
            bg.paste(background, box=(120, 120), mask=background)
            bg.paste(white, box=((1020 + 30 + 110), 120), mask=white)
            bg.save(image_name + ".png")
            result_queue.put(image_name)
        else:
            raise ValueError

        paste_watermark(
            f"./files/de_id/photo_usr/{user_id}_completed.png",
            f"./files/de_id/photo_usr/{user_id}_completed_wm.png",
        )

        result_queue.put(image_name)
    except KeyError as _ex:
        print(_ex)
        result_queue.put(f"Error:Ошибка в предоставленных данных:\n")
    except ValueError as _ex:
        print(_ex)
        result_queue.put(f"Error:Ошибка при сохранении результата:\n")
    except Exception as _ex:
        print(_ex)
        result_queue.put(f"Error:Ошибка при генерации:\n")
